package com.panda.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.panda.common.core.domain.AjaxResult;
import com.panda.common.core.domain.entity.SysDictData;
import com.panda.common.core.domain.entity.SysUser;
import com.panda.common.core.domain.model.LoginUser;
import com.panda.common.core.redis.RedisCache;
import com.panda.common.utils.DateUtils;
import com.panda.common.utils.DictUtils;
import com.panda.system.common.constant.Constants;
import com.panda.system.common.constant.EnumConstants;
import com.panda.system.domain.*;
import com.panda.system.dto.TaskFpDto;
import com.panda.system.mapper.PandaTaskDetailMapper;
import com.panda.system.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 任务完成明细Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-01-02
 */
@Service
@Transactional
public class PandaTaskDetailServiceImpl implements IPandaTaskDetailService 
{
    private static final Logger log = LoggerFactory.getLogger(PandaTaskDetailServiceImpl.class);
    @Autowired
    private PandaTaskDetailMapper pandaTaskDetailMapper;

    @Autowired
    private IPandaTaskService taskService;

    @Autowired
    private IPandaTaskMonitoringService taskMonitoringService;

    @Autowired
    private IPandaWorkbenchService workbenchService;

    @Autowired
    private ITPandaRebatesTaskService itPandaRebatesTaskService;

    @Autowired
    private ITPandaTaskUserService taskUserService;

    @Autowired
    private ITPandaEvalutionTaskService tPandaEvalutionTaskService;

    @Autowired
    private ISysUserService iSysUserService;

    @Autowired
    private RedisCache redisCache;

    /**
     * 查询任务完成明细
     * 
     * @param taskDetailId 任务完成明细ID
     * @return 任务完成明细
     */
    @Override
    public PandaTaskDetail selectPandaTaskDetailById(Long taskDetailId)
    {
        return pandaTaskDetailMapper.selectPandaTaskDetailById(taskDetailId);
    }

    /**
     * 查询任务完成明细列表
     * 
     * @param pandaTaskDetail 任务完成明细
     * @return 任务完成明细
     */
    @Override
    public List<PandaTaskDetail> selectPandaTaskDetailList(PandaTaskDetail pandaTaskDetail)
    {
        return pandaTaskDetailMapper.selectPandaTaskDetailList(pandaTaskDetail);
    }

    /**
     * 新增任务完成明细
     * 
     * @param pandaTaskDetail 任务完成明细
     * @return 结果
     */
    @Override
    public int insertPandaTaskDetail(PandaTaskDetail pandaTaskDetail)
    {
        pandaTaskDetail.setCreateTime(DateUtils.getNowDate());
        pandaTaskDetail.setStatus(EnumConstants.TaskDetailStatus.NEW_CREATE.getCode());
        return pandaTaskDetailMapper.insertPandaTaskDetail(pandaTaskDetail);
    }

    /**
     * 修改任务完成明细
     * 
     * @param pandaTaskDetail 任务完成明细
     * @return 结果
     */
    @Override
    public int updatePandaTaskDetail(PandaTaskDetail pandaTaskDetail)
    {
        pandaTaskDetail.setUpdateTime(DateUtils.getNowDate());
        return pandaTaskDetailMapper.updatePandaTaskDetail(pandaTaskDetail);
    }

    /**
     * 批量删除任务完成明细
     * 
     * @param taskDetailIds 需要删除的任务完成明细ID
     * @return 结果
     */
    @Override
    public int deletePandaTaskDetailByIds(Long[] taskDetailIds)
    {
        return pandaTaskDetailMapper.deletePandaTaskDetailByIds(taskDetailIds);
    }

    /**
     * 删除任务完成明细信息
     * 
     * @param taskDetailId 任务完成明细ID
     * @return 结果
     */
    @Override
    public int deletePandaTaskDetailById(Long taskDetailId)
    {
        return pandaTaskDetailMapper.deletePandaTaskDetailById(taskDetailId);
    }

    @Override
    public PandaTaskDetail createTaskDetail(Long taskId) {
        PandaTaskDetail taskDetail = new PandaTaskDetail();
        taskDetail.setTaskId(taskId);
        taskDetail.setTradingVolume(1);
        taskDetail.setStatus(EnumConstants.TaskDetailStatus.NEW_CREATE.getCode());
        int i = pandaTaskDetailMapper.insertPandaTaskDetail(taskDetail);
        taskDetail.setTaskDetailId(Long.valueOf(i));
        return taskDetail;
    }

    @Override
    public AjaxResult saveTaskDetail(PandaTaskDetail taskDetail, SysUser user) {
        // 保存任务完成明细
        savePandaTaskDetail(taskDetail,user);
        // 关闭待办
        closeTodo(taskDetail,user);

        TPandaTaskUser tPandaTaskUser = taskUserService.selectTPandaTaskUserByTask(taskDetail.getTaskId(), user.getUserId());
        if(EnumConstants.TransactionType.RESERVED.getCode().equals(taskDetail.getTradingType())){

            tPandaTaskUser.setBeReservedTradingVolume(tPandaTaskUser.getBeReservedTradingVolume()+1);
        }else{
            tPandaTaskUser.setBeDailyTradingVolume(tPandaTaskUser.getBeDailyTradingVolume()+1);
        }
        if(tPandaTaskUser.getDailyTradingVolume() ==tPandaTaskUser.getBeDailyTradingVolume()
                &&tPandaTaskUser.getReservedTradingVolume()==tPandaTaskUser.getBeReservedTradingVolume()){
            tPandaTaskUser.setStatus(EnumConstants.UserTaskStatus.DOWN.getCode());
        }
        taskUserService.updateTPandaTaskUser(tPandaTaskUser);

        // 修改任务信息
        PandaTask task = taskService.selectPandaTaskById(taskDetail.getTaskId());
        task.setStatus(EnumConstants.TaskType.HAVE_ORDER.getCode());
        int total = task.getRemainVolume()-taskDetail.getTradingVolume();
        if(total <=0){
            // 修改任务状态
            task.setStatus(EnumConstants.TaskType.BEEN_OPERATING.getCode());
        }
        task.setRemainVolume(total);
        taskService.updatePandaTask(task);

        //创建返款任务
        createitRebatesTaskBeforePayment(taskDetail);

        return AjaxResult.success();
    }

    private void savePandaTaskDetail(PandaTaskDetail taskDetail,SysUser user){
        // 查询任务完成明细
        PandaTaskDetail detail = new PandaTaskDetail();
        detail.setTaskId(taskDetail.getTaskId());
        detail.setResponsibleUserId(user.getUserId());
        detail.setStatus(EnumConstants.TaskDetailStatus.NEW_CREATE.getCode());
        List<PandaTaskDetail> pandaTaskDetails = pandaTaskDetailMapper.selectPandaTaskDetailList(detail);
        taskDetail.setUpdateTime(DateUtils.getNowDate());
        taskDetail.setStatus(EnumConstants.TaskDetailStatus.TO_PAY.getCode());
        taskDetail.setTradingVolume(1);
        // 计算金额
        calculateAmount(taskDetail);
        // 保存 任务完成明细
        taskDetail.setStatus(EnumConstants.TaskDetailStatus.TO_PAY.getCode());
        if(!CollectionUtils.isEmpty(pandaTaskDetails)){
            Long taskDetailId = pandaTaskDetails.get(0).getTaskDetailId();
            taskDetail.setTaskDetailId(taskDetailId);
            pandaTaskDetailMapper.updatePandaTaskDetail(taskDetail);
        }else {
            taskDetail.setCreateTime(new Date());
            pandaTaskDetailMapper.insertPandaTaskDetail(taskDetail);
        }
    }

    private void closeTodo(PandaTaskDetail taskDetail,SysUser user){
        PandaWorkbench workbench = new PandaWorkbench();
        workbench.setLinkId(taskDetail.getTaskId());
        workbench.setUserId(user.getUserId());
        List<PandaWorkbench> pandaWorkbenches = workbenchService.selectPandaWorkbenchList(workbench);
        PandaWorkbench todo = pandaWorkbenches.get(0);

        // 关闭待办
        workbenchService.shutDownTodo(todo);
        // 记录分配时间
        PandaTaskMonitoring monitoring = new PandaTaskMonitoring();
        monitoring.setOperationTime(new Date());
        monitoring.setOperationType(EnumConstants.OperationType.ORDER.getCode());
        monitoring.setOperationUserId(todo.getUserId());
        monitoring.setTaskId(taskDetail.getTaskId());
        taskMonitoringService.insertPandaTaskMonitoring(monitoring);
    }

    /**
     * 创建返款任务
     */
    private void createitRebatesTaskBeforePayment(PandaTaskDetail taskDetail){
        if(taskDetail ==null){
            return;
        }
        // 付款前返款
        if(EnumConstants.RebatesType.BEFORE_PAYMENT.getCode().equals(taskDetail.getRebatesType())){
            // 查询部门任务信息
            PandaTask task = taskService.selectPandaTaskById(taskDetail.getTaskId());
            createitRebatesTask(taskDetail,task.getPrice());
        }

    }

    @Override
    public void createitRebatesTask(PandaTaskDetail taskDetail,BigDecimal price){
        // 获取全量返款待办
        TPandaRebatesTask rebatesTask = new TPandaRebatesTask();
        rebatesTask.setStatus(EnumConstants.RebatesTypeTaskStatus.TO_REBATES.getCode());
        List<TPandaRebatesTask> tPandaRebatesTasks = itPandaRebatesTaskService.selectTPandaRebatesTaskListSys(rebatesTask);
        Map<Long, List<TPandaRebatesTask>> userTaskGroup =new HashMap<>();
        tPandaRebatesTasks = tPandaRebatesTasks.stream().filter(item->item.getResponsibleUserId()!=null).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(tPandaRebatesTasks)){
            userTaskGroup = tPandaRebatesTasks.stream().collect(Collectors.groupingBy(TPandaRebatesTask::getResponsibleUserId));
        }
        // 获取返款人员列表
        // 获取多有可分配的用户 通过岗位编码匹配
        List<SysUser> rebatesUsers = iSysUserService.selectUserListByPostCodes(Collections.singletonList(Constants.REBATES_USER),new ArrayList<>());
        rebatesUsers = filterOnLineUser(rebatesUsers);
        long userId = 0;
        List<TaskFpDto> taskFpDtos = new ArrayList<>();
        for(SysUser user:rebatesUsers){
            TaskFpDto taskFpDto = new TaskFpDto();
            taskFpDto.setUserId(user.getUserId());
            List<TPandaRebatesTask> tPandaRebatesTasks1 = userTaskGroup.get(user.getUserId());
            if(!CollectionUtils.isEmpty(tPandaRebatesTasks1)){
                taskFpDto.setTaskCount(tPandaRebatesTasks1.size());
            }
            taskFpDtos.add(taskFpDto);
        }
        if(!CollectionUtils.isEmpty(taskFpDtos)){
            // 排序 正序
            taskFpDtos.sort(TaskFpDto::compare);
            Optional<TaskFpDto> first = taskFpDtos.stream().findFirst();
            if(first.isPresent()){
                userId = first.get().getUserId();
            }
        }

        TPandaRebatesTask tPandaRebatesTask = new TPandaRebatesTask();
        tPandaRebatesTask.setRebatesAmount(taskDetail.getRebatesAmount());
        tPandaRebatesTask.setRebatesChannel(taskDetail.getRebatesChannel());
        tPandaRebatesTask.setRebatesWay(taskDetail.getRebatesWay());
        tPandaRebatesTask.setResponsibleUserId(userId);
        tPandaRebatesTask.setTaskDetailId(String.valueOf(taskDetail.getTaskDetailId()));
        tPandaRebatesTask.setStatus(EnumConstants.RebatesTypeTaskStatus.TO_REBATES.getCode());
        tPandaRebatesTask.setPrice(price);
        itPandaRebatesTaskService.insertTPandaRebatesTask(tPandaRebatesTask);
    }

    private List<SysUser> filterOnLineUser(List<SysUser> rebatesUsers){
        log.info("返款任务分配，过滤不在线返款员！");
        log.info("返款员列表：{}", JSON.toJSONString(rebatesUsers));
        Collection<String> keys = redisCache.keys(com.panda.common.constant.Constants.LOGIN_TOKEN_KEY + "*");
        List<String> onlineUserName = new ArrayList<>();
        for (String key : keys) {
            LoginUser user = redisCache.getCacheObject(key);
            onlineUserName.add(user.getUsername());
        }
        if(CollectionUtils.isEmpty(onlineUserName)){
            log.info("在线用户为空，返回全部返款员列表！");
            return rebatesUsers;
        }
        List<SysUser> filterUserList = rebatesUsers.stream().filter(item -> onlineUserName.contains(item.getUserName())).collect(Collectors.toList());

        if(CollectionUtils.isEmpty(filterUserList)){
            log.info("过滤后返款员列表为空，返回全部返款员列表！");
            return rebatesUsers;
        }
        log.info("过滤后返款员列表：{}",JSON.toJSONString(filterUserList));
        return filterUserList;
    }

    @Override
    public AjaxResult createEvaluationTodo(PandaTaskDetail pandaTaskDetail) {
        if(pandaTaskDetail ==null || pandaTaskDetail.getTaskDetailId() ==null){
            return AjaxResult.error("生成评价待办失败，任务完成明细Id为空！");
        }
        pandaTaskDetail = pandaTaskDetailMapper.selectPandaTaskDetailById(pandaTaskDetail.getTaskDetailId());
        if(pandaTaskDetail ==null || pandaTaskDetail.getTaskDetailId() ==null){
            return AjaxResult.error("生成评价待办失败，任务完成明细不存在！");
        }
        // 判断是否已生成
        TPandaEvalutionTask tPandaEvalutionTask  = new TPandaEvalutionTask();
        tPandaEvalutionTask.setResponsibleUserId(pandaTaskDetail.getResponsibleUserId());
        tPandaEvalutionTask.setTaskDetailId(String.valueOf(pandaTaskDetail.getTaskId()));
        tPandaEvalutionTask.setEvalutionType(0);
        List<TPandaEvalutionTask> tPandaEvalutionTasks = tPandaEvalutionTaskService.selectTPandaEvalutionTaskList(tPandaEvalutionTask);
        if(!CollectionUtils.isEmpty(tPandaEvalutionTasks)){
            return AjaxResult.error("生成评价待办失败，待办已存在！");
        }

        TPandaEvalutionTask newPandaEvalutionTask  = new TPandaEvalutionTask();
        newPandaEvalutionTask.setTaskDetailId(String.valueOf(pandaTaskDetail.getTaskDetailId()));
        newPandaEvalutionTask.setResponsibleUserId(pandaTaskDetail.getResponsibleUserId());
        newPandaEvalutionTask.setStatus(EnumConstants.SysStatus.OPEN.getCode());
        newPandaEvalutionTask.setEvalutionType(0);
        tPandaEvalutionTaskService.insertTPandaEvalutionTask(newPandaEvalutionTask);
        return AjaxResult.success();
    }

    @Override
    public List<PandaTaskDetail> getAllTaskDetailByTodo(PandaWorkbench todo) {
        PandaTaskDetail pandaTaskDetail = new PandaTaskDetail();
        pandaTaskDetail.setTaskId(todo.getLinkId());
        pandaTaskDetail.setStatus(EnumConstants.TaskDetailStatus.NEW_CREATE.getCode());
        pandaTaskDetail.setResponsibleUserId(todo.getUserId());
        List<PandaTaskDetail> pandaTaskDetails = selectPandaTaskDetailList(pandaTaskDetail);
        return pandaTaskDetails;
    }

    @Override
    public List<PandaTaskDetail> selectPandaTaskDetailReport(PandaTaskDetail pandaTaskDetail) {
        return pandaTaskDetailMapper.selectPandaTaskDetailReport(pandaTaskDetail);
    }

    @Override
    public void closeTaskDetail(Long taskDetailId) {
        pandaTaskDetailMapper.closeTaskDetail(taskDetailId);
    }

    /**
     * 计算返款金额
     * @param taskDetail
     */
    private void calculateAmount(PandaTaskDetail taskDetail){
        BigDecimal amount = BigDecimal.ZERO;
        EnumConstants.RebatesAmount[] rebatesAmounts = EnumConstants.RebatesAmount.values();
        for(EnumConstants.RebatesAmount config:rebatesAmounts){
            List<SysDictData> dictConfig = DictUtils.getDictCache(config.getDict());
            Map<String,SysDictData> dictMap =new HashMap<>();
            dictConfig.forEach(item->dictMap.put(item.getDictValue(),item));
            try {
                Field field = taskDetail.getClass().getDeclaredField(config.getField());
                field.setAccessible(true);
                Object key = field.get(taskDetail);
                SysDictData sysDictData = dictMap.get(key);
                if(sysDictData!=null&&sysDictData.getRemark()!=null){
                    BigDecimal lineAmount = new BigDecimal(sysDictData.getRemark());
                    amount = amount.add(lineAmount);
                }
               
            } catch (NoSuchFieldException | IllegalAccessException e) {
                e.printStackTrace();
            }

        }
        taskDetail.setRebatesAmount(amount);
    }
}
